package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"time"
)

// FileInfo 文件信息结构体
type FileInfo struct {
	Name    string
	Path    string
	IsDir   bool
	Size    int64
	ModTime time.Time
}

// ListNginxConfFiles 列出指定目录下的所有文件和文件夹
func ListNginxConfFiles(dirPath string) ([]FileInfo, error) {
	log.Printf("Listing files in directory: %s\n", dirPath)

	// 检查目录是否存在
	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
		return nil, fmt.Errorf("directory does not exist: %s", dirPath)
	}

	files, err := ioutil.ReadDir(dirPath)
	if err != nil {
		return nil, fmt.Errorf("failed to read directory: %v", err)
	}

	var fileInfos []FileInfo
	for _, file := range files {
		fileInfos = append(fileInfos, FileInfo{
			Name:    file.Name(),
			Path:    filepath.Join(dirPath, file.Name()),
			IsDir:   file.IsDir(),
			Size:    file.Size(),
			ModTime: file.ModTime(),
		})
	}

	log.Printf("Found %d items in directory: %s\n", len(fileInfos), dirPath)
	return fileInfos, nil
}

// ReadNginxConfFile 读取配置文件内容
func ReadNginxConfFile(filePath string) (string, error) {
	log.Printf("Reading file: %s\n", filePath)

	content, err := ioutil.ReadFile(filePath)
	if err != nil {
		return "", fmt.Errorf("failed to read file: %v", err)
	}

	return string(content), nil
}

// BackupNginxConfFile 备份配置文件
func BackupNginxConfFile(filePath string) (string, error) {
	log.Printf("Backing up file: %s\n", filePath)

	// 生成备份文件名（加上时间戳）
	timestamp := time.Now().Format("20060102_150405")
	backupPath := fmt.Sprintf("%s.backup_%s", filePath, timestamp)

	// 复制文件
	source, err := os.Open(filePath)
	if err != nil {
		return "", fmt.Errorf("failed to open source file: %v", err)
	}
	defer source.Close()

	destination, err := os.Create(backupPath)
	if err != nil {
		return "", fmt.Errorf("failed to create backup file: %v", err)
	}
	defer destination.Close()

	_, err = io.Copy(destination, source)
	if err != nil {
		return "", fmt.Errorf("failed to copy file: %v", err)
	}

	log.Printf("File backed up successfully: %s\n", backupPath)
	return backupPath, nil
}

// BackupNginxConfDir 备份目录
func BackupNginxConfDir(dirPath string) (string, error) {
	log.Printf("Backing up directory: %s\n", dirPath)

	// 生成备份目录名（加上时间戳）
	timestamp := time.Now().Format("20060102_150405")
	backupPath := fmt.Sprintf("%s.backup_%s", dirPath, timestamp)

	// 使用 cp 命令复制整个目录
	cmd := exec.Command("cp", "-r", dirPath, backupPath)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("failed to backup directory: %v, output: %s", err, string(output))
	}

	log.Printf("Directory backed up successfully: %s\n", backupPath)
	return backupPath, nil
}

// CreateNginxConfFile 创建新文件
func CreateNginxConfFile(filePath string, content string) error {
	log.Printf("Creating file: %s\n", filePath)

	// 检查文件是否已存在
	if _, err := os.Stat(filePath); !os.IsNotExist(err) {
		return fmt.Errorf("file already exists: %s", filePath)
	}

	err := ioutil.WriteFile(filePath, []byte(content), 0644)
	if err != nil {
		return fmt.Errorf("failed to create file: %v", err)
	}

	log.Printf("File created successfully: %s\n", filePath)
	return nil
}

// CreateNginxConfDir 创建新目录
func CreateNginxConfDir(dirPath string) error {
	log.Printf("Creating directory: %s\n", dirPath)

	// 检查目录是否已存在
	if _, err := os.Stat(dirPath); !os.IsNotExist(err) {
		return fmt.Errorf("directory already exists: %s", dirPath)
	}

	err := os.MkdirAll(dirPath, 0755)
	if err != nil {
		return fmt.Errorf("failed to create directory: %v", err)
	}

	log.Printf("Directory created successfully: %s\n", dirPath)
	return nil
}

// UpdateNginxConfFile 更新配置文件（会先备份）
func UpdateNginxConfFile(filePath string, content string) error {
	log.Printf("Updating file: %s\n", filePath)

	// 检查文件是否存在
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		return fmt.Errorf("file does not exist: %s", filePath)
	}

	// 备份原文件
	_, err := BackupNginxConfFile(filePath)
	if err != nil {
		return fmt.Errorf("failed to backup file: %v", err)
	}

	// 写入新内容
	err = ioutil.WriteFile(filePath, []byte(content), 0644)
	if err != nil {
		return fmt.Errorf("failed to update file: %v", err)
	}

	log.Printf("File updated successfully: %s\n", filePath)
	return nil
}

// DeleteNginxConfFile 删除文件（不备份）
func DeleteNginxConfFile(filePath string) error {
	log.Printf("Deleting file: %s\n", filePath)

	// 检查文件是否存在
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		return fmt.Errorf("file does not exist: %s", filePath)
	}

	// 删除文件
	err := os.Remove(filePath)
	if err != nil {
		return fmt.Errorf("failed to delete file: %v", err)
	}

	log.Printf("File deleted successfully: %s\n", filePath)
	return nil
}

// DeleteNginxConfDir 删除目录（不备份）
func DeleteNginxConfDir(dirPath string) error {
	log.Printf("Deleting directory: %s\n", dirPath)

	// 检查目录是否存在
	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
		return fmt.Errorf("directory does not exist: %s", dirPath)
	}

	// 删除目录
	err := os.RemoveAll(dirPath)
	if err != nil {
		return fmt.Errorf("failed to delete directory: %v", err)
	}

	log.Printf("Directory deleted successfully: %s\n", dirPath)
	return nil
}

// RenameNginxConfFileOrDir 重命名文件或目录（会先备份）
func RenameNginxConfFileOrDir(oldPath string, newPath string) error {
	log.Printf("Renaming %s to %s\n", oldPath, newPath)

	// 检查源是否存在
	fileInfo, err := os.Stat(oldPath)
	if os.IsNotExist(err) {
		return fmt.Errorf("source does not exist: %s", oldPath)
	}

	// 检查目标是否已存在
	if _, err := os.Stat(newPath); !os.IsNotExist(err) {
		return fmt.Errorf("target already exists: %s", newPath)
	}

	// 备份原文件/目录
	if fileInfo.IsDir() {
		_, err = BackupNginxConfDir(oldPath)
	} else {
		_, err = BackupNginxConfFile(oldPath)
	}
	if err != nil {
		return fmt.Errorf("failed to backup before rename: %v", err)
	}

	// 重命名
	err = os.Rename(oldPath, newPath)
	if err != nil {
		return fmt.Errorf("failed to rename: %v", err)
	}

	log.Printf("Renamed successfully from %s to %s\n", oldPath, newPath)
	return nil
}

// TestNginxConfig 测试 Nginx 配置
func TestNginxConfig() error {
	log.Println("Testing Nginx configuration...")

	cmd := exec.Command("nginx", "-t")
	output, err := cmd.CombinedOutput()
	log.Printf("Nginx test output: %s\n", string(output))

	if err != nil {
		return fmt.Errorf("nginx configuration test failed: %v, output: %s", err, string(output))
	}

	log.Println("Nginx configuration test passed")
	return nil
}

// ReloadNginx 重载 Nginx 配置
func ReloadNginx() error {
	log.Println("Reloading Nginx...")

	// 1. 测试配置
	if err := TestNginxConfig(); err != nil {
		return err
	}

	// 2. 重载配置
	cmd := exec.Command("nginx", "-s", "reload")
	output, err := cmd.CombinedOutput()
	log.Printf("Nginx reload output: %s\n", string(output))

	if err != nil {
		return fmt.Errorf("failed to reload nginx: %v, output: %s", err, string(output))
	}

	log.Println("Nginx reloaded successfully")
	return nil
}

// RestartNginxNew 重启 Nginx（新方式）
func RestartNginxNew() error {
	log.Println("Restarting Nginx...")

	// 1. 测试配置
	if err := TestNginxConfig(); err != nil {
		return err
	}

	// 2. 停止 Nginx
	log.Println("Stopping Nginx...")
	stopCmd := exec.Command("nginx", "-s", "stop")
	stopOutput, err := stopCmd.CombinedOutput()
	log.Printf("Nginx stop output: %s\n", string(stopOutput))
	if err != nil {
		log.Printf("Warning: failed to stop nginx (might not be running): %v\n", err)
		// 继续执行，因为 Nginx 可能没有运行
	}

	// 等待 Nginx 完全停止
	time.Sleep(2 * time.Second)

	// 3. 启动 Nginx
	log.Println("Starting Nginx...")
	startCmd := exec.Command("nginx")
	startOutput, err := startCmd.CombinedOutput()
	log.Printf("Nginx start output: %s\n", string(startOutput))
	if err != nil {
		return fmt.Errorf("failed to start nginx: %v, output: %s", err, string(startOutput))
	}

	log.Println("Nginx restarted successfully")
	return nil
}
